home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / stk-3.0 / stk-3 / blt-for-STk-3.0 / bltCutbuffer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-26  |  6.8 KB  |  266 lines

  1. /*
  2.  * bltCutbuffer.c --
  3.  *
  4.  * Copyright 1993-1994 by AT&T Bell Laboratories.
  5.  * Permission to use, copy, modify, and distribute this software
  6.  * and its documentation for any purpose and without fee is hereby
  7.  * granted, provided that the above copyright notice appear in all
  8.  * copies and that both that the copyright notice and warranty
  9.  * disclaimer appear in supporting documentation, and that the
  10.  * names of AT&T Bell Laboratories any of their entities not be used
  11.  * in advertising or publicity pertaining to distribution of the
  12.  * software without specific, written prior permission.
  13.  *
  14.  * AT&T disclaims all warranties with regard to this software, including
  15.  * all implied warranties of merchantability and fitness.  In no event
  16.  * shall AT&T be liable for any special, indirect or consequential
  17.  * damages or any damages whatsoever resulting from loss of use, data
  18.  * or profits, whether in an action of contract, negligence or other
  19.  * tortuous action, arising out of or in connection with the use or
  20.  * performance of this software.
  21.  *
  22.  */
  23. #include "blt.h"
  24. #include <X11/Xproto.h>
  25.  
  26. #ifndef CUTBUFFER_VERSION
  27. #define CUTBUFFER_VERSION "1.0"
  28. #endif
  29.  
  30. /* ARGSUSED */
  31. static int
  32. RotateErrorProc(clientData, errEventPtr)
  33.     ClientData clientData;
  34.     XErrorEvent *errEventPtr;
  35. {
  36.     int *errorPtr = (int *)clientData;
  37.  
  38.     *errorPtr = TCL_ERROR;
  39.     return 0;
  40. }
  41.  
  42. static int
  43. GetCutNumber(interp, string, bufferPtr)
  44.     Tcl_Interp *interp;
  45.     char *string;
  46.     int *bufferPtr;
  47. {
  48.     int number;
  49.  
  50.     if (Tcl_GetInt(interp, string, &number) != TCL_OK) {
  51.     return TCL_ERROR;
  52.     }
  53.     if ((number < 0) || (number > 7)) {
  54.     Tcl_AppendResult(interp, "bad buffer number \"", string, "\"",
  55.         (char *)NULL);
  56.     return TCL_ERROR;
  57.     }
  58.     *bufferPtr = number;
  59.     return TCL_OK;
  60. }
  61.  
  62. static char *
  63. GetCutBuffer(tkwin, buffer)
  64.     Tk_Window tkwin;
  65.     int buffer;
  66. {
  67.     char *dataPtr;
  68.     int numBytes;
  69.     int limit;
  70.     register char *p;
  71.     register int i;
  72.     int c;
  73.  
  74.     dataPtr = XFetchBuffer(Tk_Display(tkwin), &numBytes, buffer);
  75.     if (dataPtr == NULL) {
  76.     return NULL;
  77.     }
  78.     if (dataPtr[numBytes - 1] == '\0') {
  79.     limit = numBytes - 1;
  80.     } else {
  81.     limit = numBytes;
  82.     }
  83.     for (p = dataPtr, i = 0; i < limit; i++, p++) {
  84.     c = (unsigned char)*p;
  85.     if (c == 0) {
  86.         *p = '@';        /* Convert embedded NUL bytes */
  87.     }
  88.     }
  89.     if (limit == numBytes) {
  90.     char *newPtr;
  91.  
  92.     newPtr = (char *)malloc(numBytes + 1);
  93.     if (newPtr == NULL) {
  94.         return NULL;
  95.     }
  96.     memcpy(newPtr, dataPtr, numBytes);
  97.     newPtr[numBytes] = '\0';
  98.     free(dataPtr);
  99.     dataPtr = newPtr;
  100.     }
  101.     return (dataPtr);
  102. }
  103.  
  104. static int
  105. RotateCutBuffer(tkwin, buffer)
  106.     Tk_Window tkwin;
  107.     int buffer;
  108. {
  109.     int error = TCL_OK;
  110.     Tk_ErrorHandler handler;
  111.  
  112.     handler = Tk_CreateErrorHandler(Tk_Display(tkwin), BadMatch,
  113.     X_RotateProperties, -1, RotateErrorProc, (ClientData)&error);
  114.     XRotateBuffers(Tk_Display(tkwin), buffer);
  115.     Tk_DeleteErrorHandler(handler);
  116.     XSync(Tk_Display(tkwin), False);
  117.     return (error);
  118. }
  119.  
  120. /*
  121.  *----------------------------------------------------------------------
  122.  *
  123.  * CutBufferCmd --
  124.  *
  125.  *    This procedure is invoked to process the "cutbuffer" Tcl
  126.  *    command. See the user documentation for details on what it does.
  127.  *
  128.  * Results:
  129.  *    A standard Tcl result.
  130.  *
  131.  * Side effects:
  132.  *    None.
  133.  *
  134.  *----------------------------------------------------------------------
  135.  */
  136. /* ARGSUSED */
  137. static int
  138. CutbufferCmd(clientData, interp, argc, argv)
  139.     ClientData clientData;    /* Main window associated with
  140.                  * interpreter.*/
  141.     Tcl_Interp *interp;        /* Current interpreter. */
  142.     int argc;            /* Number of arguments. */
  143.     char **argv;        /* Argument strings. */
  144. {
  145.     Tk_Window tkwin = (Tk_Window)clientData;
  146.     int buffer;            /* cut buffer number (0-7) */
  147.     char c;
  148.     int length;
  149.  
  150.     if (argc < 2) {
  151.     Tcl_AppendResult(interp, "wrong # args: should be \"",
  152.         argv[0], " option ?args?\"", (char *)NULL);
  153.     return TCL_ERROR;
  154.     }
  155.     c = argv[1][0];
  156.     length = strlen(argv[1]);
  157.     if ((c == 'g') && (strncmp(argv[1], "get", length) == 0)) {
  158.     char *string;
  159.  
  160.     if (argc > 3) {
  161.         Tcl_AppendResult(interp, "wrong # args: should be \"",
  162.         argv[0], " get ?buffer?\"", (char *)NULL);
  163.         return TCL_ERROR;
  164.     }
  165.     buffer = 0;
  166.     if (argc == 3) {
  167.         if (GetCutNumber(interp, argv[2], &buffer) != TCL_OK) {
  168.         return TCL_ERROR;
  169.         }
  170.     }
  171.     string = GetCutBuffer(tkwin, buffer);
  172.     if (string != NULL) {
  173.         Tcl_SetResult(interp, string, TCL_DYNAMIC);
  174.     }
  175. #ifdef STk_CODE
  176.     STk_stringify_result(interp, interp->result);
  177. #endif
  178.     return TCL_OK;
  179.  
  180.     } else if ((c == 'r') && (strncmp(argv[1], "rotate", length) == 0)) {
  181.     int count;
  182.  
  183.     if ((argc < 2) || (argc > 3)) {
  184.         Tcl_AppendResult(interp, "wrong # args: should be \"",
  185.         argv[0], " rotate ?buffer?\"", (char *)NULL);
  186.         return TCL_ERROR;
  187.     }
  188.     count = 1;        /* Default: rotate one position */
  189.     if (argc == 3) {
  190.         if (Tcl_GetInt(interp, argv[2], &count) != TCL_OK) {
  191.         return TCL_ERROR;
  192.         }
  193.         if ((count < 0) || (count > 8)) {
  194.         Tcl_AppendResult(interp, "bad rotate count \"", argv[2], "\"",
  195.             (char *)NULL);
  196.         return TCL_ERROR;
  197.         }
  198.     }
  199.     if (RotateCutBuffer(tkwin, count) != TCL_OK) {
  200.         Tcl_AppendResult(interp, "\"", argv[0], " ", argv[1],
  201.         "\": all cut buffers not set", (char *)NULL);
  202.         return TCL_ERROR;
  203.     }
  204.     return TCL_OK;
  205.     } else if ((c == 's') && (strncmp(argv[1], "set", length) == 0)) {
  206.     if ((argc < 2) || (argc > 4)) {
  207.         Tcl_AppendResult(interp, "wrong # args: should be \"",
  208.         argv[0], " set value ?buffer?\"", (char *)NULL);
  209.         return TCL_ERROR;
  210.     }
  211.     buffer = 0;
  212.     if (argc == 4) {
  213.         if (GetCutNumber(interp, argv[3], &buffer) != TCL_OK) {
  214.         return TCL_ERROR;
  215.         }
  216.     }
  217.     XStoreBuffer(Tk_Display(tkwin), argv[2], strlen(argv[2]) + 1, buffer);
  218.     return TCL_OK;
  219.     } else {
  220.     Tcl_AppendResult(interp, "bad option \"", argv[1],
  221.         "\": should be get, rotate, or set", (char *)NULL);
  222.     return TCL_ERROR;
  223.     }
  224. }
  225.  
  226. /*
  227.  *----------------------------------------------------------------------
  228.  *
  229.  * Blt_CutbufferInit --
  230.  *
  231.  *    This procedure is invoked to initialize the "cutbuffer" Tcl
  232.  *    command. See the user documentation for details on what it does.
  233.  *
  234.  * Results:
  235.  *    A standard Tcl result.
  236.  *
  237.  * Side effects:
  238.  *    None.
  239.  *
  240.  *----------------------------------------------------------------------
  241.  */
  242.  
  243. int
  244. Blt_CutbufferInit(interp)
  245.     Tcl_Interp *interp;
  246. {
  247.     Tk_Window tkwin;
  248.  
  249.     if (Blt_FindCmd(interp, "blt_cutbuffer", (ClientData *)NULL) == TCL_OK) {
  250.     Tcl_AppendResult(interp, "\"blt_cutbuffer\" command already exists",
  251.         (char *)NULL);
  252.     return TCL_ERROR;
  253.     }
  254.     tkwin = Tk_MainWindow(interp);
  255.     if (tkwin == NULL) {
  256.     Tcl_AppendResult(interp, "\"blt_cutbuffer\" requires Tk",
  257.         (char *)NULL);
  258.     return TCL_ERROR;
  259.     }
  260.     Tcl_SetVar2(interp, "blt_versions", "blt_cutbuffer", CUTBUFFER_VERSION,
  261.     TCL_GLOBAL_ONLY);
  262.     Tcl_CreateCommand(interp, "blt_cutbuffer", CutbufferCmd, (ClientData)tkwin,
  263.     (Tcl_CmdDeleteProc *)NULL);
  264.     return TCL_OK;
  265. }
  266.